<?php


namespace business\elasticsearch\services;


use business\elasticsearch\models\BigDataProjectModel;

class BigDataProjectService
{
    public function getDataList(
        $keyword,
        $province,
        $city,
        $area,
        $companyArea,
        $companyType,
        $fitmentFeeLabel,
        $propertyCategoryLabel,
        $openingTimeStart,
        $openingTimeEnd,
        $deliveryTimeStart,
        $deliveryTimeEnd,
        $isPriceGtAvg,
        $createdTime,
        $tags,
        $organizingCode = [],
        $page = 1,
        $pageSize = 20)
    {
        $condition = $this->constructCondition(
            $keyword,
            $province,
            $city,
            $area,
            $companyArea,
            $companyType,
            $fitmentFeeLabel,
            $propertyCategoryLabel,
            $openingTimeStart,
            $openingTimeEnd,
            $deliveryTimeStart,
            $deliveryTimeEnd,
            $isPriceGtAvg,
            $createdTime,
            $tags,
            $organizingCode
        );

        $query = BigDataProjectModel::find()->query($condition);

        $highlight = [
            'pre_tags' => ['<em class="_high">'],
            'post_tags' => ['</em>'],
            "fields" => [
                "project_title" => new \stdClass(),
                "developer_name" => new \stdClass()
            ]
        ];
        $query->highlight($highlight);
        $query->orderBy(['opening_time' => SORT_DESC, 'id' => SORT_DESC]);

        //分页处理
        $query->offset(($page - 1) * $pageSize)->limit($pageSize);
        $searchData = $query->createCommand()->search();

        $result = ['total' => 0, 'list' => []];
        if (!empty($searchData)) {
            $data = $searchData["hits"]["hits"];
            $total = $searchData["hits"]["total"];

            //数据处理
            $result['total'] = $total;
            foreach ($data as $dv) {
                $tmp = $dv['_source'];
                $tmp['nameSuggest'] = $tmp['project_title'];
                if (!empty($dv['highlight'])) {
                    foreach ($dv['highlight'] as $key => $value) {
                        $tmp[$key . 'HL'] = isset($value[0]) ? $value[0] : '';
                    }
                }

                if (empty($tmp['developer_id']) || empty($tmp['developer_logo'])) {
                    $tmp['developer_id'] = '';
                    $tmp['developer_logo'] = '';
                }

                $tmp = $this->formatProject($tmp);
                $result['list'][] = $tmp;
            }
        }

        return $result;
    }

    private function constructCondition(
        $keyword = [],
        $province = [],
        $city = [],
        $area = [],
        $companyArea = [],
        $companyType = [],
        $fitmentFeeLabel = [],
        $propertyCategoryLabel = [],
        $openingTimeStart = '',
        $openingTimeEnd = '',
        $deliveryTimeStart = '',
        $deliveryTimeEnd = '',
        $isPriceGtAvg = [],
        $createdTime = '',
        $tags = [],
        $organizingCode = []
    )
    {
        $query = [];
        $slop = !empty(\Yii::$app->params['CommonDataDeveloperSlop']) ? \Yii::$app->params['CommonDataDeveloperSlop'] : 2;
        $must = [];
        $query['function_score']['query']['bool']['must'] = &$must;

        //项目关键词
        if (!empty($keyword)) {
            $keyShould = [];
            $must[] = ['bool' => ['should' => &$keyShould]];

            foreach ($keyword as $k) {

                $projectBool = [];
                $projectBool[] = [
                    'match_phrase' => ['project_title' => ["query" => $k, "boost" => 3, 'slop' => $slop]]
                ];
                $keyShould[] = ["bool" => ["must" => $projectBool]];

                $developerBool = [];
                $developerBool[] = [
                    'match_phrase' => ['developer_name' => ["query" => $k, "boost" => 3, 'slop' => $slop]]
                ];
                $keyShould[] = ["bool" => ["must" => $developerBool]];

            }
        }
        if (!empty($organizingCode)) {
            $must[] = ["terms" => ['organizing_code.keyword' => $organizingCode]];
        }

        // 省市
        if (!empty($province)) {
            $must[] = ["terms" => ['province_code' => $province]];
        }
        if (!empty($city)) {
            $must[] = ["terms" => ['city_code' => $city]];
        }

        //地区
        if (!empty($area)) {
            $shouldArea = [];
            $must[] = ['bool' => ['should' => &$shouldArea]];
            $shouldArea[] = ["terms" => ['province_code' => $area]];
            $shouldArea[] = ["terms" => ['city_code' => $area]];
        }

        //企业地区
        if (!empty($companyArea)) {
            $shouldCompanyArea = [];
            $must[] = ['bool' => ['should' => &$shouldCompanyArea]];
            $shouldCompanyArea[] = ["terms" => ['company_province_code' => $companyArea]];
            $shouldCompanyArea[] = ["terms" => ['company_city_code' => $companyArea]];
        }

        //企业类型
        if (!empty($companyType)) {
            $must[] = ["terms" => ['company_type_label' => $companyType]];
        }

        //企业标签
        if (!empty($companyLabel)) {
            $must[] = ["terms" => ['company_label_arr' => $companyLabel]];
        }

        //高端项目标签
        if (!empty($isPriceGtAvg)) {
            $must[] = ["terms" => ['is_price_gt_avg' => $isPriceGtAvg]];
        }

        // 装修状态
        if (!empty($fitmentFeeLabel)) {
            $must[] = ["terms" => ['fitment_fee_label' => $fitmentFeeLabel]];//数组
        }

        // 项目类型
        if (!empty($propertyCategoryLabel)) {
            $must[] = ["terms" => ['property_category_label' => $propertyCategoryLabel]];
        }

        // 开盘时间
        $openingRange = [];
        if (!empty($openingTimeStart)) {
            $openingRange['gte'] = date('Y-m-d', strtotime($openingTimeStart)) . " 00:00:00";
        }
        if (!empty($openingTimeEnd)) {
            $openingRange['lt'] = date('Y-m-d', strtotime($openingTimeEnd)) . " 23:59:59";
        }
        if (!empty($openingRange)) {
            $must[] = ['range' => ['opening_time' => $openingRange]];
        }

        // 交房时间
        $deliveryRange = [];
        if (!empty($deliveryTimeStart)) {
            $deliveryRange['gte'] = date('Y-m-d', strtotime($deliveryTimeStart)) . " 00:00:00";
        }
        if (!empty($deliveryTimeEnd)) {
            $deliveryRange['lt'] = date('Y-m-d', strtotime($deliveryTimeEnd)) . " 23:59:59";
        }
        if (!empty($deliveryRange)) {
            $must[] = ['range' => ['delivery_time' => $deliveryRange]];
        }

        if (!empty($createdTime)) {
            $dateRange = [];
            $dateRange['from'] = $createdTime;
            $dateRange['to'] = date('Y-m-d H:i:s', time());
            $must[] = ['range' => ['updated_at' => $dateRange]];
        }

        //企业标签
        if (!empty($tags)) {
            $tagShould = [];
            foreach ($tags as $k => $v) {
                if (!empty($v)) {
                    $tagShould[] = ['term' => [$k => $v]];
                }
            }
            $must[] = [
                'bool' => ['should' => $tagShould]
            ];
        }

        return $query;
    }

    public function guessNames($keyword, $pageSize)
    {
        $page = 1;

        $query = [];
        if (!empty($keyword)) {
            $query['function_score']['query']['bool']['must'][] = [
                'match_phrase' => ['project_title' => $keyword]
            ];
        }

        $query = BigDataProjectModel::find()->query($query);

        //高亮处理
        $highlight = [
            'pre_tags' => ['<em class="_high">'],
            'post_tags' => ['</em>'],
            "fields" => [
                "project_title" => new \stdClass(),
            ]
        ];
        $query->highlight($highlight);
        $query->orderBy(['_score' => SORT_DESC]);

        //分页处理
        $query->offset(($page - 1) * $pageSize)->limit($pageSize);
        $data = $query->asArray()->all();

        //数据处理
        $result = [];
        foreach ($data as $dv) {
            $item = array();
            $tmp = $dv['_source'];
            $tmp['nameSuggest'] = $tmp['project_title'];
            if (!empty($dv['highlight'])) {
                foreach ($dv['highlight'] as $key => $value) {
                    $tmp[$key . 'HL'] = isset($value[0]) ? $value[0] : '';
                }
            }
            $item['title'] = $tmp['project_title'];
            $item['titleHL'] = $tmp['project_titleHL'];
            $result[] = $item;
        }
        return $result;
    }

    public function formatProject($data)
    {
        //1、显示赋值：因为 es 的值如果为 null 会没有字段
        $return_params = [
            'pulsar_time' => 'string',
            'id' => 'string',
            'src_uid' => 'string',
            'uid' => 'string',
            'organizing_code' => 'string',
            'developer_name' => 'string',
            'project_title' => 'string',
            'province' => 'string',
            'province_code' => 'string',
            'city' => 'string',
            'city_code' => 'string',
            'company_province_code' => 'string',
            'company_city_code' => 'string',
            'opening_time' => 'string',
            'delivery_time' => 'string',
            'created_at' => 'string',
            'updated_at' => 'string',
            'developer_id' => 'string',
            'developer_logo' => 'string',
            'company_type_label' => 'string',
            'fitment_fee_label' => 'string',
            'property_category_label' => 'string',
            'price' => 'int',
            'price_city_avg' => 'string',
            'is_price_gt_avg' => 'string',
            'new_house_on_num' => 'float',
            'new_house_deal_num' => 'float',
            'new_house_deal_money' => 'float',
            'new_house_sale_rate' => 'float',
            'developer_top_100_label' => 'string',
            'new_decorate_expand_label' => 'string',
            'new_land_usage_expand_label' => 'string',
            'new_area_expand_label' => 'string',
            'price_gt_avg_label' => 'string',
            'urban_investment_label' => 'string',
            'address' => 'string',
            'developer_nameHL' => 'string',
            'project_titleHL' => 'string'
        ];

        foreach ($return_params as $rk => $rv) {
            $tmp = isset($data[$rk]) ? $data[$rk] : '';
            $tmp = $tmp === '1990-01-01 00:00:00' ? '' : $tmp;
            if ($rv == 'int') {
                $data[$rk] = (int)$tmp;
            } elseif ($rv == 'array') {
                $data[$rk] = empty($tmp) ? [] : $tmp;
            } elseif ($rv == 'float') {
                $data[$rk] = (float)$tmp;
            } else {
                $data[$rk] = $tmp;
            }

        }

        return $data;
    }
}